package rest.jbpm.svg;

import com.google.inject.internal.Maps;
import org.dom4j.Element;

import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: xEviL
 * Date: 26.10.11
 * Time: 15:06
 * To change this template use File | Settings | File Templates.
 */
class JbpmTransition {
    private Element el = null;
    private String from = null;
    private Double k = 0.8;
    private double computedLabelX = -50;
    private double computedLabelY = -20;
    private Integer[][] _coords;
    private Map<String,Number> choiseDistrib = null;

    public JbpmTransition(String _from, Element _el){
        el = _el;
        from = _from;
    }
    public String draw(Map<String,JbpmElement> model){
        int pCAlen = 0;
        String[] polylineCoordsA = null;
        String polylineCoords;
        String labelCoords;
        if ((el.attribute("g") != null ) && el.attribute("g").getValue().contains(":") && !el.attribute("g").getValue().endsWith(":")) {
            labelCoords = (el.attribute("g").getValue().split(":"))[1];
            polylineCoordsA = (((el.attribute("g").getValue().split(":"))[0]).split(";"));
            pCAlen = polylineCoordsA.length;
            polylineCoords = (((el.attribute("g").getValue().split(":"))[0]).replace(";", " "));
        }else{
            polylineCoords = "";
            if ((el.attribute("g") != null ) && !el.attribute("g").getValue().endsWith(":") ){
                labelCoords=el.attribute("g").getValue();
            }

            else
                labelCoords="-50,-20";
        }

        // добавили +2 для координат начала и конца, которые получаются из state'ов
        Integer[][] coords = new Integer[pCAlen + 2][2];

        // вообще говоря первую точку следует считать по границе фигуры
        coords[0][0] = model.get(from).getElCenterX();
        coords[0][1] = model.get(from).getElCenterY();

        // координаты конечной точки - тоже следует считать по границе фигуры
        coords[coords.length-1][0] = model.get(el.attribute("to").getValue()).getElCenterX();
        coords[coords.length-1][1] = model.get(el.attribute("to").getValue()).getElCenterY();

        // остальные координаты
        if (polylineCoordsA != null){
            int i = 1;
            for (String dot:polylineCoordsA){
                coords[i][0] = Integer.parseInt(dot.split(",")[0]);
                coords[i][1] = Integer.parseInt(dot.split(",")[1]);
                i++;
            }
        }

        // координаты подписи: относительно средней точки линии или относительно
        // центра средней линии
        int labelX = 0;
        int labelY = 0;
        if ((coords.length % 2) == 0){
            labelX = (coords[coords.length/2][0] + coords[coords.length/2 - 1][0]) / 2 + Integer.parseInt(labelCoords.split(",")[0]);
            labelY = (coords[coords.length/2][1] + coords[coords.length/2 - 1][1]) / 2 + Integer.parseInt(labelCoords.split(",")[1]);
        }else{
            labelX = coords[coords.length/2][0] + Integer.parseInt(labelCoords.split(",")[0]);
            labelY = coords[coords.length/2][1] + Integer.parseInt(labelCoords.split(",")[1]);
        }

        // рассчет по границе фигуры начальной и конечной точек соединения
        //coords[0][0] = model.get(from).getBorderX(coords[1][0],coords[1][1]);
        //coords[0][1] = model.get(from).getBorderY(coords[1][0],coords[1][1]);

        coords[0][0] = model.get(from).getElCenterX();
        coords[0][1] = model.get(from).getElCenterY();

        coords[coords.length-1][0] = model.get(el.attribute("to").getValue()).getElCenterX();
        coords[coords.length-1][1] = model.get(el.attribute("to").getValue()).getElCenterY();

        int arrx = model.get(el.attribute("to").getValue()).getBorderX(coords[coords.length-2][0],coords[coords.length-2][1]);//coords[coords.length-1][0]
        int arry = model.get(el.attribute("to").getValue()).getBorderY(coords[coords.length-2][0],coords[coords.length-2][1]);//

        polylineCoords = coords[0][0]+","+coords[0][1]+" "+polylineCoords+" "+coords[coords.length-1][0]+","+coords[coords.length-1][1];

        // рисование
        // стрелка
        String arr = "<g fill=\"none\" stroke=\"black\" stroke-width=\"1\" transform=\"translate("+arrx+","+arry+")\" >";
        arr += "<g transform=\"rotate("+model.get(el.attribute("to").getValue()).getBorderAngle(coords[coords.length-2][0],coords[coords.length-2][1])+")\">";
        //arr += "<line x1=\"1\" y1=\"0\" x2=\"14\" y2=\"2\" />";
        //arr += "<line x1=\"1\" y1=\"0\" x2=\"14\" y2=\"-2\" />";
        arr += "<polygon points=\"0,0 14,2 14,-2\" style=\"stroke:black;fill:black;stroke-width:1\" />";
        arr += "</g></g>";

        // подпись
        if (el.attribute("name") != null){
            computedLabelX = labelX;
            computedLabelY = labelY;
        }

        _coords = coords;

        return "\t<polyline points=\""+polylineCoords+"\" style=\"fill:none;stroke:black;stroke-width:1\" />\n"+arr;

    }

    public int getXMax(){
        if (_coords == null)
            return 0;

        int max = 0;
        for (Integer[] xy:_coords){
            if (xy[0] > max)
                max = xy[0];
        }

        return max+50;
    }

    public int getYMax(){
        if (_coords == null)
            return 0;

        int max = 0;
        for (Integer[] xy:_coords){
            if (xy[1] > max)
                max = xy[1];
        }

        return max+50;
    }

    public String drawLabel(){

        if (el.attribute("name") == null)
            return "";

        int rand = (int)Math.round(Math.random()*10000);
        String textId = "t_"+rand;
        String boxId = "b_"+rand;

        String out ="";


        out += "<rect rx=\"2\" ry=\"2\" id=\""+boxId+"\" x=\""+computedLabelX+"\" y=\"" + computedLabelY + "\" width=\"1\" height=\"1\" style=\"fill:white; fill-opacity:0.5;\" />";

        out += "<text id=\""+textId+"\" font-size=\""+(14.0*k)+"px\" x=\""+computedLabelX+"\" y=\""+(computedLabelY-(14.0*k))+"\" font-family=\"sans-serif\" fill=\"blue\" >"+el.attribute("name").getValue();
        if (choiseDistrib != null)
            out += "<tspan style=\"fill:coral;\">"+getChoiseDistribution()+"</tspan>";
        out += "</text>";

        out += "<script>\n" +
                "var "+textId+" = document.getElementById(\""+textId+"\");\n"+
                "var "+boxId+" = document.getElementById(\""+boxId+"\");\n"+
                "var bbox = "+textId+".getBBox();\n" +
                boxId +".setAttribute(\"width\",bbox.width);\n" +
                boxId +".setAttribute(\"height\",bbox.height);\n" +
                "</script>\n";

        return out;
    }

    public void setChoiseDistribution(Map<String,Number> chd){
        choiseDistrib = chd;
    }

    public String getChoiseDistribution(){
        if (choiseDistrib == null)
            return "";

        // String from - здесь хранится имя начального узла транзишена
        // el.attribute("to").getValue() - здесь хранится имя конечного узла транзишена

        Long all_hits = (long)0;

        // сумма всех переходов
        for (Number num: choiseDistrib.values()){
            all_hits += num.longValue();
        }

        try { 
            return "~" + Math.round(((double) choiseDistrib.get(el.attribute("name").getValue()).longValue() / (double) all_hits)*10000)/100.0 + "%";
        } catch (NullPointerException npe) {
            return "~0%";
        }

    }

}
